#include "DeviceMgr.hpp"
#include "ConnMgr.hpp"
#include "KieperException.hpp"
#include "ExceptionUtil.hpp"
#include "Log.hpp"

#include <algorithm>

#include <boost/foreach.hpp>
#include <boost/bind.hpp>
#include <boost/thread/mutex.hpp>

namespace kieper {
    DeviceMgr::DeviceMgr() : nextMsgId_(0) {}
    DeviceMgr::~DeviceMgr() {}

    void DeviceMgr::addConnMgr(ConnMgr* connMgr) {
        connMgr->initialize();
        connMgrs_.push_back(connMgr);
    }

    void DeviceMgr::findDevices() {
        BOOST_FOREACH(ConnMgr& connMgr, connMgrs_) {
            DeviceMapPtr devicesFromMgr = connMgr.findDevices();
            devices_.transfer(devicesFromMgr->begin(), devicesFromMgr->end(),
                *devicesFromMgr);
        }
    }

    Device& DeviceMgr::getDevice(uint16_t deviceId) {
        DeviceMap::iterator it = devices_.find(deviceId);
        if (it == devices_.end()) {
            THROW(KieperException, "Device not found");
        } 
        return *(it->second);
    }

    void DeviceMgr::startPacketProcessors() {
        for_each(connMgrs_.begin(), connMgrs_.end(), bind(&ConnMgr::startPacketProcessor, _1));
        bool allProcessorsReady = false;
        while (!allProcessorsReady) {
            BOOST_FOREACH(ConnMgr& mgr, connMgrs_) {
                if (!mgr.isPacketProcessorReady()) {
                    continue;
                }
            }
            allProcessorsReady = true;
        }
    }
}
